/***************************************************************************
 *   This is a part of the NextCAD Web APP.                                *
 *   Copyright (C) AMCAX, All rights reserved.                             *
 ***************************************************************************/

// import { Alert, Button } from 'antd';
import {
  CommandDialog,
  EPSILON_SQ,
  pickedFaceData,
  pickedLineData,
  PickType,
} from '@amcax/base';
import { docMgr } from '@app-cad/module';
import { useCommand } from '@app-cad/common/hooks/useCommand';
import { CurvedBaseCommand, CurvedCmdDialogParams } from '@app-cad/types';
import i18n from 'i18next';
import { useEffect, useState } from 'react';
import { wsApi } from '@app-base/server';
import { getIdOfPickedObj } from '@app-base/common/utils/render';
import { eventCenterManager } from '@app-base/common/events/EventCenterManager';
import { defaultEventCenter } from '@app-base/common/events/DefaultEventCenter';
import { sketchEventCenter } from '@app-base/environments/nextcad/events/SketchEventCenter';
import { renderSketch } from '@app-base/common/utils';
import { CommandFormWrapper } from '@app-base/common/components/command-form';
import {
  MultiPickInput,
  PickInputValueType,
} from '@app-base/common/components/pick-input/3d';
import { CommandFormFooter } from '@app-base/common/components/command-form/footer';
import { Vector3, Vector3Tuple } from 'three-legacy';

function CmdIntersect3D({ title, onClose, props }: CurvedCmdDialogParams) {
  const [elements, setElements] = useState<(pickedLineData | pickedFaceData)[]>(
    [],
  );

  useEffect(() => {
    eventCenterManager.switchTo(defaultEventCenter().id);

    return () => {
      eventCenterManager.switchTo(sketchEventCenter().id);
    };
  }, []);

  const isFormDataValid = () =>
    elements.length >= 1 && elements.every((c) => c != null);

  const checkAndFinishDraw = async () => {
    if (!isFormDataValid()) {
      return;
    }

    await execute();
    onClose();
  };

  const { initingEdit, isLoading } = useCommand('cmd-intersect-3d', {
    onClose,
    finishDraw: checkAndFinishDraw,
    editDxid: props?.shape,
  });

  const execute = async () => {
    const sketchId = docMgr.getCurrentSketchDxid();
    const res = await wsApi.execCmd({
      e: 'SKETCHER',
      c: 'Intersect3D',
      o: sketchId,
      a: {
        elements: elements.map((e) => getIdOfPickedObj(e)),
      },
    });

    await renderSketch(sketchId, res);

    onClose();
  };

  return (
    <CommandDialog
      onClose={onClose}
      title={title}
      placement='topLeft'
    >
      <CommandFormWrapper>
        <MultiPickInput
          disabled={initingEdit}
          value={elements}
          isMulti
          onPick={(v) => {
            setElements(
              // 过滤与草图平行的平面
              v.filter((element) => {
                if (element.idInfo.t === PickType.PLANE) {
                  const normal: Vector3Tuple =
                    element.modelData.faces?.[element?.idInfo?.i]?.normals?.[0];

                  if (normal == null) {
                    return true;
                  }
                  const normalVec = new Vector3(...normal).normalize();

                  const currentSketchNormal =
                    sketchEventCenter().getSketchInfo()
                      .frame[1] as Vector3Tuple;
                  const sketchNormalVec = new Vector3(
                    ...currentSketchNormal,
                  ).normalize();

                  // 1是同方向单位向量的点积
                  if (
                    Math.abs(Math.abs(normalVec.dot(sketchNormalVec)) - 1) <
                    EPSILON_SQ
                  ) {
                    return false;
                  }
                }

                return true;
              }),
            );
          }}
          autoFocus
          placeholder='请输入相交元素'
          allowPickType={[PickInputValueType.Curve, PickInputValueType.Surface]}
        />
        <CommandFormFooter
          isSubmitLoading={isLoading}
          isSubmitDisabled={!isFormDataValid() || initingEdit}
          submitText='完成'
          onClose={onClose}
          onSubmit={checkAndFinishDraw}
        />
      </CommandFormWrapper>
    </CommandDialog>
  );
}

export const cmdIntersect3D: CurvedBaseCommand = {
  id: 'CmdIntersect3D',
  label: 'command.intersect3D',
  icon: 'commands/sketch/intersect-3D-elements',
  group: 'sketch',
  help: {
    remark: 'tips.redo',
  },
  create: (label, onClose, props) => (
    <CmdIntersect3D
      title={i18n.t(label)}
      onClose={onClose}
      props={props}
    />
  ),
};
